package goxml

import (
	"encoding/xml"
	"fmt"
	"io"
	"os"
	"strings"
)

func DecodeXmlFile(file string) *Element {
	xmlFile, err := os.Open(file)
	if err != nil {
		return nil
	}
	defer xmlFile.Close()
	return decodeElement(xml.NewDecoder(xmlFile))
}

func DecodeXmlText(text string) *Element {
	return decodeElement(xml.NewDecoder(strings.NewReader(text)))
}

func decodeElement(decoder *xml.Decoder) *Element {
	//var a any
	element := NewElement()
	for {
		t, err := decoder.Token()
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Errorf("%v", err)
		}
		switch se := t.(type) {
		case xml.StartElement:
			decodeStartElement(decoder, se, element)
		case xml.CharData:
			content := string(se)
			// fmt.Println("xml.CharData ", content)
			element.Text = strings.TrimSpace(content)
		case xml.EndElement:
			// fmt.Println("xml.EndElement ", se.Name.Local)
			return element
		}
	}
	return element
}

func decodeStartElement(decoder *xml.Decoder, se xml.StartElement, element *Element) {
	element.Name = se.Name.Local
	for _, attr := range se.Attr {
		element.Attributes[attr.Name.Local] = attr.Value
	}
	for {
		t, err := decoder.Token()
		if err == io.EOF || err != nil {
			break
		}
		switch se := t.(type) {
		case xml.StartElement:
			// fmt.Println("xml.StartElement ", se.Name.Local)
			element1 := NewElement()
			element.Elements = append(element.Elements, element1)
			decodeStartElement(decoder, se, element1)
		case xml.CharData:
			content := string(se)
			element.Text = strings.TrimSpace(content)
		case xml.EndElement:
			// fmt.Println("xml.EndElement ", se.Name.Local)
			return
		}
	}
}
